<!-- 表格下拉选择组件 license by http://eleadmin.com -->
<template>
  <ele-basic-select
    ref="select"
    :value="value"
    :multiple="multiple"
    :disabled="disabled"
    :size="size"
    :clearable="clearable"
    :collapse-tags="collapseTags"
    :placeholder="placeholder"
    :automatic-dropdown="automaticDropdown"
    :popper-class="['ele-table-select-dropdown', popperClass].join(' ')"
    :popper-options="popperOptions"
    :popper-width="popperWidth"
    :id="id"
    :name="name"
    :autocomplete="autocomplete"
    :selected-label="selectedLabel"
    :selected="selected"
    :visible.sync="visible"
    @clear="onClear"
    @remove-tag="onRemoveTag"
    @focus="onFocus"
    @blur="onBlur"
  >
    <ele-pro-table
      ref="table"
      :row-key="valueKey"
      :current.sync="current"
      :selection.sync="selection"
      :highlight-current-row="!multiple"
      :datasource="tableConfig.datasource"
      :method="tableConfig.method"
      :where="tableConfig.where"
      :headers="tableConfig.headers"
      :content-type="tableConfig.contentType"
      :request="tableConfig.request"
      :response="tableConfig.response"
      :parse-data="tableConfig.parseData"
      :parse-param="tableConfig.parseParam"
      :need-page="tableConfig.needPage"
      :init-load="tableConfig.initLoad"
      :loading="tableConfig.loading"
      :columns="tableConfig.columns"
      :height="tableConfig.height"
      :max-height="tableConfig.maxHeight"
      :stripe="tableConfig.stripe"
      :border="tableConfig.border"
      :size="tableConfig.size"
      :fit="tableConfig.fit"
      :show-header="tableConfig.showHeader"
      :row-class-name="tableConfig.rowClassName"
      :row-style="tableConfig.rowStyle"
      :cell-class-name="tableConfig.cellClassName"
      :cell-style="tableConfig.cellStyle"
      :header-row-class-name="tableConfig.headerRowClassName"
      :header-row-style="tableConfig.headerRowStyle"
      :header-cell-class-name="tableConfig.headerCellClassName"
      :header-cell-style="tableConfig.headerCellStyle"
      :empty-text="tableConfig.emptyText"
      :default-expand-all="tableConfig.defaultExpandAll"
      :expand-row-keys="tableConfig.expandRowKeys"
      :default-sort="tableConfig.defaultSort"
      :tooltip-effect="tableConfig.tooltipEffect"
      :show-summary="tableConfig.showSummary"
      :sum-text="tableConfig.sumText"
      :summary-method="tableConfig.summaryMethod"
      :span-method="tableConfig.spanMethod"
      :select-on-indeterminate="tableConfig.selectOnIndeterminate"
      :indent="tableConfig.indent"
      :lazy="tableConfig.lazy"
      :load="tableConfig.load"
      :tree-props="tableConfig.treeProps"
      :page-size="tableConfig.pageSize"
      :pager-count="tableConfig.pagerCount"
      :current-page="tableConfig.currentPage"
      :layout="tableConfig.layout"
      :page-sizes="tableConfig.pageSizes"
      :popper-class="tableConfig.popperClass"
      :prev-text="tableConfig.prevText"
      :next-text="tableConfig.nextText"
      :hide-on-single-page="tableConfig.hideOnSinglePage"
      :tools-theme="tableConfig.toolsTheme"
      :title="tableConfig.title"
      :sub-title="tableConfig.subTitle"
      :toolkit="tableConfig.toolkit"
      :columns-sort="tableConfig.columnsSort"
      :row-click-checked="tableConfig.rowClickChecked"
      :row-click-checked-intelligent="tableConfig.rowClickCheckedIntelligent"
      :toolbar="tableConfig.toolbar"
      :tool-style="tableConfig.toolStyle"
      :tool-class="tableConfig.toolClass"
      :toolkit-style="tableConfig.toolkitStyle"
      :pagination-style="tableConfig.paginationStyle"
      :full-z-index="tableConfig.fullZIndex"
      :auto-amend-page="tableConfig.autoAmendPage"
      :parent-id-name="tableConfig.parentIdName"
      :default-parent-id="tableConfig.defaultParentId"
      :parent-id-field="tableConfig.parentIdField"
      @done="onTableDone"
      @row-click="onRowClick"
    >
      <template
        v-for="name in Object.keys($scopedSlots)"
        :slot="name"
        slot-scope="{ row, column, $index }"
      >
        <slot
          :name="name"
          v-bind:row="row"
          v-bind:column="column"
          v-bind:$index="$index"
        />
      </template>
    </ele-pro-table>
  </ele-basic-select>
</template>

<script>
  import EleBasicSelect from '../../ele-basic-select';
  import EleProTable from '../../ele-pro-table';

  export default {
    name: 'EleTableSelect',
    components: { EleBasicSelect, EleProTable },
    emits: [
      'input',
      'change',
      'focus',
      'blur',
      'clear',
      'remove-tag',
      'visible-change'
    ],
    props: {
      // 绑定值
      value: {
        type: [Number, String, Array],
        required: true
      },
      // 是否多选
      multiple: Boolean,
      // 是否禁用
      disabled: Boolean,
      // 尺寸
      size: String,
      // 是否可以清空选项
      clearable: Boolean,
      // 多选时是否将选中值按文字的形式展示
      collapseTags: Boolean,
      // 占位符
      placeholder: String,
      // 是否在输入框获得焦点后自动弹出选项菜单
      automaticDropdown: Boolean,
      // 下拉框的类名
      popperClass: String,
      // popper.js 的参数
      popperOptions: Object,
      // popper宽度
      popperWidth: {
        type: [String, Number],
        default: 480
      },
      // input 的 id 属性
      id: String,
      // input 的 name 属性
      name: String,
      // input 的 autocomplete 属性
      autocomplete: {
        type: String,
        default: 'off'
      },
      // value的键名
      valueKey: {
        type: String,
        default: 'value'
      },
      // label的键名
      labelKey: {
        type: String,
        default: 'label'
      },
      // 表格配置
      tableConfig: {
        type: Object,
        required: true
      }
    },
    data() {
      return {
        // 单选选中展示的文本
        selectedLabel: '',
        // 选中的数据
        selected: [],
        // popover是否显示
        visible: false,
        // 表格单选选中数据
        current: null,
        // 表格多选选中数据
        selection: []
      };
    },
    methods: {
      // 更新visible
      updateVisible(value) {
        this.visible = value;
        this.$emit('visible-change', value);
      },
      // 获取焦点
      onFocus() {
        this.$emit('focus');
      },
      // 失去焦点
      onBlur() {
        this.$emit('blur');
      },
      // 清空
      onClear() {
        this.$emit('input', this.multiple ? [] : '');
        this.$emit('change', this.multiple ? [] : null);
        this.$emit('clear');
        this.visible = false;
        this.$emit('visible-change', false);
      },
      // 删除tag
      onRemoveTag(item) {
        const value = this.value.filter((v) => v !== item.value);
        this.$emit('input', value);
        this.$emit('change', value);
        this.$emit(
          'remove-tag',
          this.getRowByValue(item.value, this.selection)
        );
      },
      // value改变事件
      onValueChange(value) {
        // 单选模式
        if (!this.multiple) {
          const isEmpty = this.isEmptyValue(value);
          if (isEmpty) {
            this.selectedLabel = '';
            if (this.current) {
              this.$refs?.table?.setCurrentRow(null);
            }
          } else {
            if (!this.current || this.current[this.valueKey] !== value) {
              const row = this.getRowByValue(value);
              this.selectedLabel = row ? row[this.labelKey] : value;
              this.$refs?.table?.setCurrentRow(row);
            } else {
              const label = this.current[this.labelKey];
              this.selectedLabel = label ?? value;
            }
          }
          return;
        }
        // 多选模式
        if (value?.length) {
          const checked = [];
          const addList = [];
          const removeList = [];
          value.forEach((v) => {
            const item = this.getRowByValue(v, this.selection);
            if (item) {
              checked.push({
                label: item[this.labelKey],
                value: v
              });
            } else {
              const row = this.getRowByValue(v);
              if (row) {
                addList.push(row);
                checked.push({
                  label: row[this.labelKey],
                  value: v
                });
              } else {
                checked.push({
                  label: v,
                  value: v
                });
              }
            }
          });
          this.selected = checked;
          this.$refs?.select?.resetInputHeight();
          // 更新表格选中
          this.selection.forEach((d) => {
            if (!value.includes(d[this.valueKey])) {
              removeList.push(d);
            }
          });
          addList.forEach((d) => {
            this.$refs?.table?.toggleRowSelection(d, true);
          });
          removeList.forEach((d) => {
            this.$refs?.table?.toggleRowSelection(d, false);
          });
        } else {
          this.selected = [];
          this.$refs?.select?.resetInputHeight();
          this.$refs?.table?.clearSelection();
        }
      },
      // 单选判断是否是空值
      isEmptyValue(value) {
        return typeof value === 'undefined' || value === null || value === '';
      },
      // 获取value对应数据
      getRowByValue(value, data) {
        if (data) {
          return data.find((d) => d[this.valueKey] === value);
        } else {
          const tableData = this.$refs?.table?.tableData ?? [];
          return tableData.find((d) => d[this.valueKey] === value);
        }
      },
      // 表格渲染完成事件
      onTableDone() {
        // 单选模式回显label
        if (!this.multiple) {
          if (!this.isEmptyValue(this.value)) {
            const row = this.getRowByValue(this.value);
            if (row) {
              this.$refs?.table?.setCurrentRow(row);
              if (this.selectedLabel === this.value) {
                this.selectedLabel = row[this.labelKey];
              }
            }
          }
          return;
        }
        // 多选模式修正选中
        if (this.value?.length) {
          const addList = [];
          const removeList = [];
          this.value.forEach((v) => {
            const item = this.getRowByValue(v, this.selection);
            if (!item) {
              const row = this.getRowByValue(v);
              if (row) {
                addList.push(row);
              }
            }
          });
          this.selection.forEach((d) => {
            if (!this.value.includes(d[this.valueKey])) {
              removeList.push(d);
            }
          });
          addList.forEach((d) => {
            this.$refs?.table?.toggleRowSelection(d, true);
          });
          removeList.forEach((d) => {
            this.$refs?.table?.toggleRowSelection(d, false);
          });
        }
        this.$nextTick(() => {
          this.$refs?.select?.updatePopper();
        });
      },
      // 表格行点击事件
      onRowClick() {
        if (!this.multiple) {
          this.visible = false;
          this.$emit('visible-change', false);
        }
      },
      // 刷新表格
      reload(obj) {
        this.$refs?.table?.reload(obj);
      }
    },
    mounted() {
      if (this.multiple) {
        if (this.value?.length) {
          this.onValueChange(this.value);
        }
      } else if (!this.isEmptyValue(this.value)) {
        this.onValueChange(this.value);
      }
    },
    watch: {
      value(value) {
        this.onValueChange(value);
      },
      current(current) {
        if (!this.multiple) {
          this.$emit('input', current ? current[this.valueKey] : '');
          this.$emit('change', current);
        }
      },
      selection(selection) {
        if (this.multiple) {
          const value = selection.map((d) => d[this.valueKey]);
          this.$emit('input', value);
          this.$emit('change', selection);
        }
      }
    }
  };
</script>

<style lang="scss">
  .ele-table-select-dropdown.el-popover {
    box-sizing: border-box;
    padding: 8px;

    & > .popper__arrow {
      left: 35px !important;
    }

    & > .ele-pro-table > .el-table + .el-pagination {
      margin-top: 8px;
    }
  }
</style>
